#!/home/wcaarls/compile/bin/python

import archdesc, copy, time, signal, sys, lockdict

def printresults(nr=0, frame=0, limits=(0.5, 100, 0.1)):
  global results, startat
  
  count = startat
  
  print "% Signalled, dumping results"
  results.lock()
  for s in results.iterkeys():
    if len(results[s]) < 1:
      print "% " + str(s) + " did not complete simulation"
    else:
      if results[s][0][0] <= limits[0] and results[s][0][1] <= limits[1] and results[s][0][2] <= limits[2]:
        s.OutputMatlab(results[s], [count])
        count = count + 1
      else:
        print "% " + str(s) + " is beyond limits: " + str(results[s][0])
        
  results.unlock()
  print "% End of dump"

def maxl(l):
  m = l[0]
  for e in l[1:]:
    if e > m:
      m = e

  return m

startat = 1

try:
  startat = int(sys.argv[1])
except:
  pass

runto = 99999999

try:
  runto = int(sys.argv[2])
except:
  pass

print "% Installing signal handler"
signal.signal(signal.SIGHUP, printresults)

alltypes = ["fc", "uniring", "bus"]
allbandwidths = [100000000, 10000000, 5000000]
allcomponents = ["tm", "m24kc", "im132", "im66", "rc2", "rc4", "xl"]
allcomponentbws = copy.deepcopy(allbandwidths)
allmappers = [archdesc.MapDesc(1   , 0   , 0, 0   , 0), \
              archdesc.MapDesc(1   , 0.25, 0, 0   , 0), \
              archdesc.MapDesc(1   , 0   , 0, 0.25, 0), \
              archdesc.MapDesc(1   , 0.25, 0, 0.25, 0), \
              archdesc.MapDesc(0   , 1   , 0, 0   , 0), \
              archdesc.MapDesc(0.25, 1   , 0, 0   , 0), \
              archdesc.MapDesc(0   , 1   , 0, 0.25, 0), \
              archdesc.MapDesc(0.25, 1   , 0, 0.25, 0), \
              archdesc.MapDesc(0   , 0   , 0, 1   , 0), \
              archdesc.MapDesc(0.25, 0   , 0, 1   , 0), \
              archdesc.MapDesc(0   , 0.25, 0, 1   , 0), \
              archdesc.MapDesc(0.25, 0.25, 0, 1   , 0)]
maxcomponents = 6

results = lockdict.lockdict()

n = 1
for bandwidth in allbandwidths:
    for type in alltypes:
      for i in range(pow((maxcomponents-1),len(allcomponents))):
        components = [archdesc.ComponentDesc("camera", 0, 0, 0)]

        #drop = True
        for c in range(len(allcomponents)):
        
          #if (i/(pow((maxcomponents-1),c)))%(maxcomponents-1) > 2:
          #  drop = False
        
          for d in range((i/(pow((maxcomponents-1),c)))%(maxcomponents-1)):
            components.append(archdesc.ComponentDesc(allcomponents[c], 0, 0, 0))

        #if drop:
        #  continue
        
        # Let's not get excessive
        if len(components) > maxcomponents:
          continue
          
        # Make sure the design contains an ILP processor
        foundilp = False
        for c in components:
          if c.type == "tm" or c.type == "ss" or c.type == "m24kc":
            foundilp = True
        if not foundilp:
          continue
          
        for tt in range(5):
          for at in range(5):
            for ast in range(5):
              for e in range(5):
                if tt == 3 or at == 3 or ast == 3 or e == 3:
                  continue
              
                tot = (tt+at+ast+e)
                max = maxl([tt, at, ast, e])

                if max == 1 or max == 2 or (max == tot and tot != 0):
                  div = max/4.0
                else:
                  div = 1.0
              
                m = archdesc.MapDesc(tt/div/4.0, at/div/4.0, ast/div/4.0, e/div/4.0, 0.0)
                a = archdesc.ArchDesc(type, bandwidth, components, 2, allbandwidths, alltypes, allcomponents, allcomponentbws)
                s = archdesc.SystemDesc(a, copy.deepcopy(m))
          
                print "% " + str(n) + ": " + str(s)[:20] + "..."
                
                if s.evalquick()[1] > 100:
                  print "%*" + str(n) + ": too expensive!"
                  continue
          
                results.lock()
                if s in results:
                  results.unlock()
                  print "%*" + str(n) + ": Already simulated!"
                  continue
                results.unlock()
                
                if n >= startat:
                  s.evaluate(results, "robocup")
                else:
                  results[s] = []
                
                n = n + 1
          
                if (n % 10000) == 0:
                  printresults()
                  
                if n >= runto:
                  print "%% Reached endcondition"
                  print "%% Waiting for stragglers"
                  time.sleep(10)
                  printresults()
                  sys.exit(0)

print "%% Done"
print "%% Waiting for stragglers"

time.sleep(10)

#results.lock()
#for s in results.iterkeys():
#  while len(results[s]) < 1:
#    results.unlock()
#    time.sleep(0.5)
#    results.lock()
#results.unlock()

printresults()
